home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / gtlayout-source.lha / LTP_LevelImage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  10.5 KB  |  474 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1996 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #ifdef DO_LEVEL_KIND
  15.  
  16.  
  17. /*****************************************************************************/
  18.  
  19.  
  20. STATIC VOID
  21. DrawLevelImageLeft(struct RastPort *RPort,UWORD *Pens,LevelImageInfo *Level,struct Image *Image,LONG Left,LONG Top,LONG Width,LONG Height,LONG OffsetX,LONG OffsetY)
  22. {
  23.     LONG    BorderTop    = Level->KnobTop,
  24.             BorderLeft    = Level->KnobWidth;
  25.  
  26.     Left    += OffsetX;
  27.     Top        += OffsetY;
  28.  
  29.     if(Width > 0)
  30.     {
  31.         LTP_SetAPen(RPort,Pens[SHADOWPEN]);
  32.         LTP_DrawLine(RPort,Left,Top,Left,Top + Height - 1);
  33.  
  34.         if(Width > 1)
  35.         {
  36.             LTP_DrawLine(RPort,Left + 1,Top,Left + 1,Top + Height - 2);
  37.             LTP_SetAPen(RPort,Pens[SHINEPEN]);
  38.  
  39.             WritePixel(RPort,Left + 1,Top + Height - 1);
  40.  
  41.             if(Width > 2)
  42.             {
  43.                 LTP_DrawLine(RPort,Left + 2,Top + Height - 1,Left + Width - 1,Top + Height - 1);
  44.  
  45.                 LTP_SetAPen(RPort,Pens[SHADOWPEN]);
  46.                 LTP_DrawLine(RPort,Left + 2,Top,Left + Width - 1,Top);
  47.  
  48.                 LTP_SetAPen(RPort,Pens[FILLPEN]);
  49.                 RectFill(RPort,Left + 2,Top + 1,Left + Width - 1,Top + Height - 2);
  50.             }
  51.         }
  52.  
  53.         EraseRect(RPort,Left,Top - BorderTop,Left + Width - 1,Top - 1);
  54.         LTP_EraseBox(RPort,Left,Top + Height,Width,BorderTop);
  55.         EraseRect(RPort,Left - BorderLeft,Top - BorderTop,Left - 1,Top + Height + BorderTop - 1);
  56.     }
  57.     else
  58.     {
  59.         if(Level->Position < BorderLeft && Level->Position > 0)
  60.         {
  61.             Left    = Image->LeftEdge + OffsetX;
  62.             Width    = Level->Position;
  63.  
  64.             EraseRect(RPort,Left,Top - BorderTop,Left + Width - 1,Top + Height + BorderTop - 1);
  65.         }
  66.     }
  67. }
  68.  
  69.  
  70. /*****************************************************************************/
  71.  
  72.  
  73. STATIC VOID
  74. DrawLevelImageRight(struct RastPort *RPort,UWORD *Pens,LevelImageInfo *Level,struct Image *Image,LONG Left,LONG Top,LONG Width,LONG Height,LONG OffsetX,LONG OffsetY)
  75. {
  76.     LONG    BorderTop    = Level->KnobTop,
  77.             BorderLeft    = Level->KnobWidth;
  78.  
  79.     Left    += OffsetX;
  80.     Top        += OffsetY;
  81.  
  82.     if(Width > 0)
  83.     {
  84.         LTP_SetAPen(RPort,Pens[SHINEPEN]);
  85.  
  86.         LTP_DrawLine(RPort,Left + Width - 1,Top,Left + Width - 1,Top + Height - 1);
  87.  
  88.         if(Width > 1)
  89.         {
  90.             LTP_DrawLine(RPort,Left + Width - 2,Top + 1,Left + Width - 2,Top + Height - 1);
  91.             LTP_SetAPen(RPort,Pens[SHADOWPEN]);
  92.  
  93.             WritePixel(RPort,Left + Width - 2,Top);
  94.  
  95.             if(Width > 2)
  96.             {
  97.                 LTP_DrawLine(RPort,Left,Top,Left + Width - 3,Top);
  98.  
  99.                 LTP_SetAPen(RPort,Pens[SHINEPEN]);
  100.                 LTP_DrawLine(RPort,Left,Top + Height - 1,Left + Width - 3,Top + Height - 1);
  101.  
  102.                 LTP_SetAPen(RPort,Pens[BACKGROUNDPEN]);
  103.                 RectFill(RPort,Left,Top + 1,Left + Width - 3,Top + Height - 2);
  104.             }
  105.         }
  106.  
  107.         EraseRect(RPort,Left,Top - BorderTop,Left + Width - 1,Top - 1);
  108.         LTP_EraseBox(RPort,Left,Top + Height,Width,BorderTop);
  109.         EraseRect(RPort,Left + Width,Top - BorderTop,Left + Width + BorderLeft - 1,Top + Height + BorderTop - 1);
  110.     }
  111.     else
  112.     {
  113.         Width = Image->Width - (Level->Position + 2 * BorderLeft);
  114.  
  115.         if(Width > 0)
  116.         {
  117.             Left = Image->LeftEdge + OffsetX + 2 * BorderLeft + Level->Position;
  118.  
  119.             EraseRect(RPort,Left,Top - BorderTop,Left + Width - 1,Top + Height + BorderTop - 1);
  120.         }
  121.     }
  122. }
  123.  
  124.  
  125. /*****************************************************************************/
  126.  
  127.  
  128. STATIC VOID
  129. DrawLevelImageComplete(struct Image *Image,struct RastPort *RPort,UWORD *Pens,LevelImageInfo *Level,LONG OffsetX,LONG OffsetY,BOOL Selected)
  130. {
  131.     LONG    BorderTop    = Level->KnobTop,
  132.             BorderLeft    = Level->KnobWidth,
  133.             Left,Top,
  134.             Width,Height;
  135.     LONG    Position;
  136.  
  137.     Left    = Image->LeftEdge + BorderLeft;
  138.     Top        = Image->TopEdge + BorderTop;
  139.     Width    = Image->Width - 2 * BorderLeft;
  140.     Height    = Image->Height - 2 * BorderTop;
  141.  
  142.     Position = Level->Position + Left;
  143.  
  144.     DrawLevelImageLeft(RPort,Pens,Level,Image,Left,Top,Position - BorderLeft - Left,Height,OffsetX,OffsetY);
  145.     DrawLevelImageRight(RPort,Pens,Level,Image,Position + BorderLeft,Top,Left + Width - (Position + BorderLeft),Height,OffsetX,OffsetY);
  146.  
  147.     BltBitMapRastPort(Level->Knob[Selected ? 1: 0],0,0,RPort,Left + OffsetX + Level->Position - Level->KnobWidth,Image->TopEdge + OffsetY,Level->KnobWidth * 2,Image->Height,0xC0);
  148. }
  149.  
  150.  
  151. /*****************************************************************************/
  152.  
  153.  
  154. STATIC ULONG
  155. LevelClassDraw(struct Image *Image,struct impDraw *DrawMsg,LevelImageInfo *Level)
  156. {
  157.     struct RastPort *RPort = DrawMsg->imp_RPort;
  158.  
  159.     SetAfPt(RPort,NULL,0);
  160.  
  161.     DrawLevelImageComplete(Image,RPort,Level->Pens,Level,DrawMsg->imp_Offset.X,DrawMsg->imp_Offset.Y,DrawMsg->imp_State == IDS_SELECTED);
  162.  
  163.     if(DrawMsg->imp_State == IDS_DISABLED)
  164.     {
  165.         ULONG    Ghosting    = 0x44441111;
  166.  
  167.         LONG    Left        = Image->LeftEdge    + DrawMsg->imp_Offset.X,
  168.                 Top            = Image->TopEdge    + DrawMsg->imp_Offset.Y;
  169.  
  170.         LTP_SetPens(RPort,Level->Pens[SHADOWPEN],0,JAM1);
  171.  
  172.         SetAfPt(RPort,(UWORD *)&Ghosting,1);
  173.         LTP_FillBox(RPort,Left,Top,Image->Width,Image->Height);
  174.         SetAfPt(RPort,NULL,0);
  175.     }
  176.  
  177.     return(TRUE);
  178. }
  179.  
  180.  
  181. /*****************************************************************************/
  182.  
  183.  
  184. STATIC VOID
  185. LevelClassSet(Class *class,struct Image *Image,struct opSet *SetMsg)
  186. {
  187.     LevelImageInfo    *Level = (LevelImageInfo *)INST_DATA(class,Image);
  188.     struct TagItem    *Item,*List,*PositionItem = NULL;
  189.     LONG             Width = Image->Width - 2 * Level->KnobWidth;
  190.  
  191.     List = SetMsg->ops_AttrList;
  192.  
  193.     while(Item = NextTagItem(&List))
  194.     {
  195.         switch(Item->ti_Tag)
  196.         {
  197.             case LVIA_Current:
  198.                 Level->Current = Item->ti_Data;
  199.                 break;
  200.  
  201.             case LVIA_Max:
  202.                 Level->Max = Item->ti_Data;
  203.                 break;
  204.  
  205.             case LVIA_Position:
  206.                 PositionItem = Item;
  207.                 break;
  208.         }
  209.     }
  210.  
  211.     if(PositionItem)
  212.     {
  213.         LONG Position = (LONG)PositionItem->ti_Data;
  214.  
  215.         if(Position < 0 || !Level->Max)
  216.             Position = 0;
  217.         else
  218.         {
  219.             if(Position > Width)
  220.                 Position = Width;
  221.         }
  222.  
  223.         Level->Position = Position;
  224.     }
  225.     else
  226.     {
  227.         if(Level->Max)
  228.             Level->Position = (Width * Level->Current) / Level->Max;
  229.         else
  230.             Level->Position = 0;
  231.     }
  232. }
  233.  
  234.  
  235. /*****************************************************************************/
  236.  
  237.  
  238. STATIC BOOL
  239. LevelClassGet(Class *class,struct Image *Image,struct opGet *GetMsg)
  240. {
  241.     LevelImageInfo *Level = (LevelImageInfo *)INST_DATA(class,Image);
  242.  
  243.     switch(GetMsg->opg_AttrID)
  244.     {
  245.         case LVIA_Current:
  246.             *GetMsg->opg_Storage = Level->Current;
  247.             return(TRUE);
  248.  
  249.         case LVIA_Max:
  250.             *GetMsg->opg_Storage = Level->Max;
  251.             return(TRUE);
  252.  
  253.         case LVIA_Position:
  254.             *GetMsg->opg_Storage = Level->Position;
  255.             return(TRUE);
  256.  
  257.         case LVIA_KnobWidth:
  258.             *GetMsg->opg_Storage = Level->KnobWidth;
  259.             return(TRUE);
  260.  
  261.         case IA_SupportsDisable:
  262.             *GetMsg->opg_Storage = TRUE;
  263.             return(TRUE);
  264.     }
  265.  
  266.     return(FALSE);
  267. }
  268.  
  269.  
  270. /*****************************************************************************/
  271.  
  272.  
  273. STATIC ULONG
  274. LevelClassNew(Class *class,Object *object,struct opSet *SetMsg)
  275. {
  276.     LONG             Width        = 0,
  277.                      Height     = 0;
  278.     LONG             FontWidth    = 0;
  279.     LONG             Current    = 0,
  280.                      Max        = 0;
  281.     struct DrawInfo *DrawInfo    = NULL;
  282.     struct Screen    *Screen        = NULL;
  283.     struct TagItem    *List,
  284.                     *Item;
  285.  
  286.     List = SetMsg->ops_AttrList;
  287.  
  288.     while(Item = NextTagItem(&List))
  289.     {
  290.         switch(Item->ti_Tag)
  291.         {
  292.             case LVIA_Current:
  293.                 Current = (LONG)Item->ti_Data;
  294.                 break;
  295.  
  296.             case LVIA_Max:
  297.                 Max = (LONG)Item->ti_Data;
  298.                 break;
  299.  
  300.             case LVIA_DrawInfo:
  301.                 DrawInfo = (struct DrawInfo *)Item->ti_Data;
  302.                 break;
  303.  
  304.             case LVIA_FontWidth:
  305.                 FontWidth = Item->ti_Data;
  306.                 break;
  307.  
  308.             case LVIA_Screen:
  309.                 Screen = (struct Screen *)Item->ti_Data;
  310.                 break;
  311.  
  312.             case IA_Width:
  313.                 Width = Item->ti_Data;
  314.                 break;
  315.  
  316.             case IA_Height:
  317.                 Height = Item->ti_Data;
  318.                 break;
  319.         }
  320.     }
  321.  
  322.     if(Width && Height >= 4 && DrawInfo && Screen)
  323.     {
  324.         struct Image *Image;
  325.  
  326.         if(Image = (struct Image *)DoSuperMethodA(class,object,(Msg)SetMsg))
  327.         {
  328.             struct RastPort __aligned     RastPort;
  329.             struct RastPort                *RPort;
  330.             LevelImageInfo                *Level = (LevelImageInfo *)INST_DATA(class,Image);
  331.             LONG                         QuarterWidth,
  332.                                          KnobWidth,
  333.                                          LevelHeight,
  334.                                          i;
  335.             LONG                         Depth;
  336.             struct BitMap                *Friend;
  337.             LONG                         Shine,Shadow,Back,Fill;
  338.             UWORD                        *Pens;
  339.  
  340.             memset(Level,0,sizeof(LevelImageInfo));
  341.  
  342.             QuarterWidth    = (FontWidth + 3) / 4,
  343.             KnobWidth        = 3 * QuarterWidth,
  344.             LevelHeight        = 2 + (2 * QuarterWidth * DrawInfo->dri_Resolution.X) / DrawInfo->dri_Resolution.Y;
  345.  
  346.             if(LevelHeight >= Height)
  347.                 LevelHeight = Height / 4;
  348.  
  349.             if(LevelHeight < 2)
  350.             {
  351.                 if(Height > 2)
  352.                     LevelHeight = 2;
  353.                 else
  354.                     LevelHeight = Height;
  355.             }
  356.  
  357.             Level->KnobWidth    = KnobWidth;
  358.             Level->KnobTop        = (Height - LevelHeight) / 2;
  359.             Level->LevelHeight    = LevelHeight;
  360.             Level->Max            = Max;
  361.             Level->Current        = Current;
  362.             Level->Pens            = DrawInfo->dri_Pens;
  363.  
  364.             if(Max)
  365.                 Level->Position = ((Width - 2 * KnobWidth) * Current) / Max;
  366.             else
  367.                 Level->Position = 0;
  368.  
  369.             Friend = Screen->RastPort.BitMap;
  370.  
  371.             Depth = LTP_GetDepth(Friend);
  372.  
  373.             Width = Level->KnobWidth * 2;
  374.  
  375.             for(i = 0 ; i < 2 ; i++)
  376.             {
  377.                 if(!(Level->Knob[i] = LTP_CreateBitMap(Width,Height,Depth,Friend,FALSE)))
  378.                 {
  379.                     CoerceMethod(class,object,OM_DISPOSE);
  380.  
  381.                     return(NULL);
  382.                 }
  383.             }
  384.  
  385.             InitRastPort(RPort = &RastPort);
  386.  
  387.             Pens = Level->Pens;
  388.  
  389.             Back = Pens[BACKGROUNDPEN];
  390.  
  391.             for(i = 0 ; i < 2 ; i++)
  392.             {
  393.                 RPort->BitMap = Level->Knob[i];
  394.  
  395.                 Fill    = Pens[i ? FILLPEN : BACKGROUNDPEN];
  396.                 Shine    = Pens[SHINEPEN];
  397.                 Shadow    = Pens[SHADOWPEN];
  398.  
  399.                 SetRast(RPort,Fill);
  400.  
  401.                 LTP_RenderBevel(RPort,Pens,0,0,Width,Height,FALSE,2);
  402.  
  403.                 if(Fill == Shine || Fill == Shadow)
  404.                     Shine = Shadow = Back;
  405.  
  406.                 LTP_SetAPen(RPort,Shine);
  407.                 LTP_DrawLine(RPort,Width / 2,2,Width / 2,Height - 3);
  408.  
  409.                 LTP_SetAPen(RPort,Shadow);
  410.                 LTP_DrawLine(RPort,Width / 2 - 1,2,Width / 2 - 1,Height - 3);
  411.             }
  412.  
  413.             return((ULONG)Image);
  414.         }
  415.     }
  416.  
  417.     return(NULL);
  418. }
  419.  
  420.  
  421. STATIC VOID
  422. LevelClassDispose(Class *class,Object *object,Msg msg)
  423. {
  424.     LevelImageInfo    *Level = (LevelImageInfo *)INST_DATA(class,object);
  425.     LONG             i;
  426.  
  427.     for(i = 0 ; i < 2 ; i++)
  428.     {
  429.         if(Level->Knob[i])
  430.         {
  431.             WaitBlit();
  432.  
  433.             break;
  434.         }
  435.     }
  436.  
  437.     for(i = 0 ; i < 2 ; i++)
  438.         LTP_DeleteBitMap(Level->Knob[i],FALSE);
  439. }
  440.  
  441. /*****************************************************************************/
  442.  
  443.  
  444. ULONG __saveds __asm
  445. LTP_LevelClassDispatcher(REG(a0) Class *class,REG(a2) Object *object,REG(a1) Msg msg)
  446. {
  447.     switch(msg->MethodID)
  448.     {
  449.         case IM_DRAW:
  450.             return(LevelClassDraw((struct Image *)object,(struct impDraw *)msg,(LevelImageInfo *)INST_DATA(class,object)));
  451.  
  452.         case OM_SET:
  453.             LevelClassSet(class,(struct Image *)object,(struct opSet *)msg);
  454.             break;
  455.  
  456.         case OM_GET:
  457.             if(LevelClassGet(class,(struct Image *)object,(struct opGet *)msg))
  458.                 return(TRUE);
  459.             else
  460.                 break;
  461.  
  462.         case OM_NEW:
  463.             return(LevelClassNew(class,object,(struct opSet *)msg));
  464.  
  465.         case OM_DISPOSE:
  466.             LevelClassDispose(class,object,msg);
  467.  
  468.             // Falls down through to the default case...
  469.     }
  470.  
  471.     return(DoSuperMethodA(class,object,msg));
  472. }
  473. #endif    /* DO_LEVEL_KIND */
  474.